package com.gqzm.iaas.component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gqzm.iaas.config.RestRequest;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @ClassName: {@link TaskCache}
 * @description: TODO
 * @author: peter qin
 * @date: 2023 11 22
 * @version: 1.0
 **/
@Slf4j
@Component
public class TaskCache {

    //任务信息映射表
    private static final Map<String, TaskInfo> taskMap = new ConcurrentHashMap<>(16);
    //任务队列
    private static final BlockingQueue<String> queue = new LinkedBlockingQueue<>();

    private static final ExecutorService executor = Executors.newFixedThreadPool(1);

    private static final AtomicBoolean executeFlag = new AtomicBoolean(true);

    private static String pyPath;
    @Resource
    private RestRequest restRequest;

    @Value("${gqzm.allmask.py-path:}")
    public void setPyPath(String pp) {
        if (StringUtils.isBlank(pyPath)) {
            pyPath = pp;
        }
    }

    @Value("${gqzm.allmask.identity-url:http://localhost:8082/api/gqzm/v1/iaas/task/create}")
    private String identityUrl;

    public void startLoopTask() {
        executor.execute(() -> {
            while (executeFlag.get()) {
                try {
                    String taskId = queue.poll();
                    TaskInfo task;
                    if (null == taskId
                            || (task = taskMap.get(taskId)) == null) {
                        Thread.yield();
                        continue;
                    }
                    for (String pic : task.getPicNames()) {
                        //调用python命令
                        task.setCurrentIndex(task.getCurrentIndex() + 1);
                        try {
//                            int code = execPythonCmd(task.getPicPath(), pic, task.getResultPath());
//                            log.info("识别结果:{}", code);
//                            if (code == 0) {
//                                task.getFails().add(pic);
//                            }
                            JSONObject param = new JSONObject();
                            param.put("image_path", task.getPicPath() + File.separator + pic);
                            param.put("json_out_path", task.getResultPath());
                            restRequest.restCall(
                                    HttpMethod.POST,
                                    identityUrl,
                                    param,
                                    null

                            );
                        } catch (Exception e) {
                            log.error("执行标注识别失败", e);
                        }
                    }
                    task.setStatus("3");
                    task.setTimestamp(System.currentTimeMillis());
                } catch (Exception e) {
                    log.error("任务执行失败", e);
                }
            }
        });
    }


    public static void setPyPathByCmd(String... pps) {
        for (String pp : pps) {
            if (pp.startsWith("-mask-all-path=")) {
                log.info("==============命令行设置pyPath: {}", pp);
                pyPath = StringUtils.substringAfterLast(pp, "-mask-all-path=");
            }
        }


    }


    public static TaskInfo getTaskInfo(String taskId) {
        TaskInfo task = taskMap.get(taskId);
        if (task != null
                && StringUtils.equals(task.getStatus(), "3")
                && System.currentTimeMillis() - task.getTimestamp() > 600000) {
            taskMap.remove(taskId);
        }
        return task;
    }


    public static synchronized void stopTask(String taskId) {
        taskMap.remove(taskId);
    }


    @SneakyThrows
    public static int execPythonCmd(
            String path,
            String picName,
            String resultPath) {
        log.info("执行目标识别{},{}", path, picName);
        //执行命令
        Process process = Runtime.getRuntime().exec(String.format(
                "python allmask.py --image_path %s --json_out_path %s",
                path + File.separator + picName,
                resultPath
        ));

        //获取命令输出流
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                log.info("命令日志: {}", line);
            }
        }
        return process.waitFor();
    }


    public static synchronized void enqueue(TaskInfo task) {
        taskMap.put(task.getTaskId(), task);
        queue.add(task.getTaskId());
    }


    @PreDestroy
    public void preDestroy() {
        executeFlag.set(Boolean.FALSE);
        if (!executor.isTerminated()) {
            executor.shutdown();
        }
    }


}
